package com.zkh.myutils.database.dbpool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;

import com.zkh.myutils.io.log.Logger;
import com.zkh.myutils.scheduled.ScheduledExecutor;
import com.zkh.myutils.utils.Assert;

/**
 * 连接池定时器
 * @author zkh
 */
final class PoolTimer {
	
	//两个定时器
	private static ScheduledFuture<?> recycleFuture;	//回收连接定时器
	private static ScheduledFuture<?> userfulCheckFuture;	//连接是否有效定时器
	//回收连接集合
	private static List<Pools> recycleList = new ArrayList<>();

	/**
	 * 添加回收检查
	 */
	public static void addRunRecycle(Pools pools) {
		//不存在，则添加
		if(!recycleList.contains(pools)) {
			recycleList.add(pools);
		}
	}
	
	/**
	 * 执行连接池连接回收操作
	 */
	public static void runRecycle() {
		//大于0，执行回收操作
		if(ConnectConfigure.getRecoveryTime()>0) {
			//间隔时间和延迟时间
			long internal = ConnectConfigure.getRecoveryTime() * 1000L;
			//初始化定时器
			recycleFuture = ScheduledExecutor.addTask(()->{
				//有回收列表
				if(!recycleList.isEmpty()) {
					//显示日志标识
					boolean showLog = ConnectConfigure.isShowPoolLog();
					//显示日志
					if(showLog) Logger.debug("开始执行连接池连接回收操作");
					//遍历连接池
					for(Pools pools: Pools.poolsMap.values()) {
						//回收池
						if(recycleList.contains(pools)) {
							//执行检查
							int num = Pools.runCheck(pools, 1);
							//显示日志
							if(showLog) Logger.debug("数据源（{}）连接回收完毕，共回收连接{}个",  pools.key, num);
						}
					}
				}
			}, internal, internal);
		}
	}
	
	/**
	 * 执行连接是否有效的检查
	 */
	public static void runUsefulCheck() {
		//间隔时间和延迟时间
		long internal = ConnectConfigure.getPingInterval() * 1000L;
		//初始化定时器
		userfulCheckFuture = ScheduledExecutor.addTask(()->{
			//显示日志标识
			boolean showLog = ConnectConfigure.isShowPoolLog();
			//显示日志
			if(showLog) Logger.debug("开始检查连接是否有效");
			//遍历连接池
			for(Pools pools: Pools.poolsMap.values()) {
				//执行检查
				int num = Pools.runCheck(pools, 2);
				//显示日志
				if(showLog) Logger.debug("数据源（{}）连接池连接检查完毕，失效被移除：{}个，使用中：{}个，空闲：{}个", pools.key, num, pools.used.size(), pools.idle.size());
			}
		}, internal, internal);
	}
	
	/**
	 * 停止定时器和线程
	 */
	public static void stopTimer() {
		Assert.doIfNotNull(recycleFuture, future->future.cancel(true));
		Assert.doIfNotNull(userfulCheckFuture, future->future.cancel(true));
		//取消定时任务
		ScheduledExecutor.shutdownIfAllCancelled();
	}
}
